package com.xindacloud.sms.adapter.service.notify;


import com.google.gson.Gson;
import com.xindacloud.sms.adapter.config.QueueNames;
import com.xindacloud.sms.adapter.dto.SqsSubmitMessageParamDTO;
import com.xindacloud.sms.adapter.dto.SubmitMessageParamDTO;
import com.xindacloud.sms.adapter.entity.SmsSubmissionRecord;
import com.xindacloud.sms.adapter.entity.SmsTaskTotal;
import com.xindacloud.sms.adapter.exchange.ExchangeAction;
import com.xindacloud.sms.adapter.exchange.ExchangeMessage;
import com.xindacloud.sms.adapter.service.business.ISmsSubmissionRecordService;
import com.xindacloud.sms.adapter.service.business.ISmsTaskTotalService;
import com.xindacloud.sms.adapter.service.business.ISmsUserService;
import com.xindacloud.sms.adapter.utils.CommonUtils;
import com.xindacloud.sms.adapter.utils.StatusEum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Component
@Slf4j
public class NotifyExecutor {


    private final NotifyServiceFactory notifyServiceFactory;
    private final QueueMessagingTemplate messagingTemplate;
    private final QueueNames queueNames;
    private final ISmsTaskTotalService taskTotalService;
    private final ISmsSubmissionRecordService submissionRecordService;
    private final ISmsUserService userService;

    @Autowired
    public NotifyExecutor(NotifyServiceFactory notifyServiceFactory, QueueMessagingTemplate messagingTemplate,
                          QueueNames queueNames, ISmsTaskTotalService taskTotalService,
                          ISmsSubmissionRecordService submissionRecordService, ISmsUserService userService) {
        this.notifyServiceFactory = notifyServiceFactory;
        this.messagingTemplate = messagingTemplate;
        this.queueNames = queueNames;
        this.taskTotalService = taskTotalService;
        this.submissionRecordService = submissionRecordService;
        this.userService = userService;
    }

    public void handleNotifyMessage(ExchangeMessage payload) {
        String action = payload.getAction();
        log.info("###### Message Action:{}", action);
        String data = new Gson().toJson(payload.getData());
        log.info("receiver Message:{}", data);
        notifyServiceFactory.getService(action, data);
    }

    @Transactional(rollbackFor = Exception.class)
    public void sendNotifyMessage(SubmitMessageParamDTO submitMessageParamDTO, String username, String password) {

        final List<String> recipientList = new ArrayList<>(new HashSet<>(submitMessageParamDTO.getRecipientList()));
        final int recipientCount = recipientList.size();
        final String taskId = taskTotalService.saveSmsTaskTotal(SmsTaskTotal.builder()
                .pendingCount(recipientCount)
                .recipientCount(recipientCount)
                .build())
                .getTaskId();
        final Integer userId = userService.queryUserInfoFor(username, password).getUserId();
        int default_record = 1000;
        int batchCount = recipientCount / default_record + (recipientCount % default_record == 0 ? 0 : 1);
        for (int i = 1; i <= batchCount; i++) {
            SqsSubmitMessageParamDTO sqsSubmitMessageDTO = new SqsSubmitMessageParamDTO();
            BeanUtils.copyProperties(submitMessageParamDTO, sqsSubmitMessageDTO);
            sqsSubmitMessageDTO.setUserId(userId);
            sqsSubmitMessageDTO.setTaskId(taskId);
            List<String> subRecipientList;
            if (batchCount == i) {
                subRecipientList = recipientList.subList((i - 1) * default_record, recipientCount);
            } else {
                subRecipientList = recipientList.subList((i - 1) * default_record, default_record * (i));
            }

            sqsSubmitMessageDTO.setRecipientList(subRecipientList);
            messagingTemplate.convertAndSend(queueNames.getSubmitSmsQueue(),
                    ExchangeMessage.builder()
                            .action(ExchangeAction.SUBMIT_SMS_ACTION)
                            .data(sqsSubmitMessageDTO)
                            .build());

            List<SmsSubmissionRecord> submissionRecordList = new ArrayList<>();
            for (String recipient : subRecipientList) {
                final SmsSubmissionRecord submissionRecord = SmsSubmissionRecord.builder()
                        .taskId(taskId)
                        .finalStatus(StatusEum.PENDING.desc)
                        .sendTo(recipient)
                        .sendFrom(sqsSubmitMessageDTO.getSender())
                        .submitStatusCode(0)
                        .messageBody(sqsSubmitMessageDTO.getMessageBody())
                        .encoding(sqsSubmitMessageDTO.getEncoding())
                        .messageCount(sqsSubmitMessageDTO.getMessageCount())
                        .projectId(CommonUtils.buildRandomUUID())
                        .userId(userId)
                        .smsType(sqsSubmitMessageDTO.getSmsType())
                        .actionType("SMS")
                        .requestType("HTTP POST")
                        .build();
                if (Objects.isNull(submissionRecordService.querySmsSubmissionRecord(submissionRecord))) {
                    submissionRecordList.add(submissionRecord);
                }
            }
            submissionRecordService.insertBatch(submissionRecordList);
        }
    }
}
